#include "framemanager.h"
#include "world.h"
#include "vehicle.h"
#include "driver.h"
#include "trafficcontrol.h"

FrameManager::FrameManager()
  : mCurrentFrameNumber(0)
{
}

FrameManager::~FrameManager()
{
  clearFrames();
}

void FrameManager::addFrame()
{
  World* w(World::instance());
  if (w)
  {
    Frame* f(new Frame(Frame::FRAME_FULL));
    f->mTime = w->gSimTime;
    foreach(Vehicle* v, w->mVehicles)
    {
      Point eng, brk, fric, drag, goal;
      v->forces(eng, brk, fric, drag);

      if (v->driver())
        goal = v->driver()->mCurrentGoal;
      f->addVehicle(new VehicleFrame(v->name(),
                                     v->type()->graphic,
                                     v->position(),
                                     v->direction().angle(),
                                     v->acceleration(),
                                     v->velocity(),
                                     eng,brk,fric,drag,
                                     goal));
    }


    foreach(TrafficControl *tc, w->mTrafficControls)
    {
      f->addTrafficControlFrame(new TrafficControlFrame(tc->intersection()->name(),
                                                        tc->intersection(),
                                                        *tc->currentState()));
    }
    mFrames.append(f);
  }
}

void FrameManager::clearFrames()
{
  mCurrentFrameNumber = 0;
  mFrames.clear();
}

Frame* FrameManager::currentFrame()
{
  if (!mFrames.empty() && mCurrentFrameNumber < (unsigned int)mFrames.size())
    return mFrames.at(mCurrentFrameNumber);
  return NULL;
}

void FrameManager::rewindFrame(unsigned int numFrames)
{
  setCurrentFrameNumber(mCurrentFrameNumber-numFrames);
}

void FrameManager::advanceFrame(unsigned int numFrames)
{
  setCurrentFrameNumber(mCurrentFrameNumber+numFrames);
}

unsigned int FrameManager::currentFrameNumber() const
{
  return mCurrentFrameNumber;
}

void FrameManager::setCurrentFrameNumber(unsigned int number)
{
  unsigned int frameCount = static_cast<unsigned int>(mFrames.size());
  if (number < 0)
    mCurrentFrameNumber = 0;
  else if (number >= frameCount)
    mCurrentFrameNumber = frameCount-1;
  else
    mCurrentFrameNumber =  number;
}

void FrameManager::toLastFrame()
{
  if (mFrames.empty())
    mCurrentFrameNumber = 0;
  else
  {
    unsigned int frameCount = static_cast<unsigned int>(mFrames.size());
    mCurrentFrameNumber = frameCount-1;
  }
}
